/**
 * @author Roger Wu
 * @version 1.0
 * added extend property oncheck
 */
 (function($){
 	$.extend($.fn, {
		jTree:function(options) {
			var item,items;
			var op = $.extend({checkFn:null, selected:"selected", exp:"expandable", coll:"collapsable", firstExp:"first_expandable", firstColl:"first_collapsable", lastExp:"last_expandable", lastColl:"last_collapsable", folderExp:"folder_expandable", folderColl:"folder_collapsable", endExp:"end_expandable", endColl:"end_collapsable",file:"file",ck:"checked", unck:"unchecked"}, options);
			return this.each(function(){
				var $this = $(this);
				var $p=$this.parents(".tree")
				var isTreeFolder=$this.hasClass("treeFolder")||$p.hasClass("treeFolder");
				var isTreeCheck=$this.hasClass("treeCheck")||$p.hasClass("treeCheck");
				var isTreeRadio=$this.hasClass("treeRadio")||$p.hasClass("treeRadio");
//				if(!$this.hasClass("tree"))$this.attr("class",$this.parents(".tree").attr("class")).attr("action",$this.parents(".tree").attr("action"));
				var cnum = $this.children().length;
				$(">li", $this).each(function(){
					var $li = $(this);
					var first = $li.prev()[0]?false:true;
					var last = $li.next()[0]?false:true; 
					$li.genTree({
						icon:isTreeFolder,
						ckbox:isTreeCheck,
						radio:isTreeRadio,
						options: op,
						level: $this.attr("level")||0,
						exp:(cnum>1?(first?op.firstExp:(last?op.lastExp:op.exp)):op.endExp),
						coll:(cnum>1?(first?op.firstColl:(last?op.lastColl:op.coll)):op.endColl),
						//exp:first?op.firstExp:(last?op.lastExp:op.exp),
						//coll:first?op.firstColl:(last?op.lastColl:op.coll),
						//showSub:(!$this.hasClass("collapse") && ($this.hasClass("expand") || (cnum>1?(first?true:false):true))),
						isLast:(cnum>1?(last?true:false):true)
					});
				});
				setTimeout(function(){
					if(isTreeCheck || isTreeRadio){
						var checkFn = eval($this.attr("oncheck")||$this.parents(".tree").attr("oncheck"));
						if(checkFn && $.isFunction(checkFn)) {
							$("div.ckbox", $this).each(function(){
								var ckbox = $(this);
								ckbox.click(function(){
									var checked = $(ckbox).hasClass("checked");
									var items = [];
									if(checked){
										var tnode = $(ckbox).parent().parent();
										var boxes = $("input", tnode);
										$(boxes).each(function(){
											items[items.length] = ckbox.parents("li").data("item");
											//items[items.length] = {name:$(this).attr("name"), value:$(this).val()};
										});		
									}else{
										items[items.length] = ckbox.parents("li").data("item");
									}
									checkFn({checked:checked, items:items});														
								});
							});
						}
					}
//					else if($this.hasClass("treeRadio")){
//						var clickFn = eval($this.attr("oncheck"));
//						if(clickFn && $.isFunction(clickFn)) {
//							$("div.radio", $this).each(function(){
//								var radio = $(this);
//								radio.click(function(){
//									clickFn(radio.parents("li").data("item"));														
//								});
//							});
//						}
//					}
					$("a", $this).click(function(event){
						$("div." + op.selected, $(this).parents("ul.tree")).removeClass(op.selected);
						var parent = $(this).parent().addClass(op.selected);
						$(".ckbox",parent).trigger("click");
						event.stopPropagation();
						$(document).trigger("click");
						if (!$(this).attr("target")) return false;
					});
					//$("li>div",$this)._contextmenu();
					$("li",$this).each(function(){
						$(this)._treemenu();
					})
				},1);
			});
		},
		reload:function(){
			var $this=$(this);
			$this.attr("loaded",false);
			$this.bindTree();
		},
		/**
		 * 绑定树
		 */
		bindTree:function(){
			var $this=$(this);
			var loaded = $this.attr("loaded");
			if(loaded=="true") return $this;
			
			var action=$this.parents(".tree").attr("action")||$this.attr("action");
			if(!action) return $this;

			var categoryId=$this.attr("category_id")||0;
			if(categoryId==0){
				var entity = $this.parents(".tree").attr("entity")||$this.attr("entity");
				action=entity+"/category";
			}else{
				action=action.replace(/\/0\//g,"/"+categoryId+"/").replace(/\{category_id}/ig,categoryId);
			}

			DWZ.get(action,function(json){
				$this.html("");
				if(!json.result||json.result.length==0) return;
				DWZ.addTree($this,json.result);
				
				$this.attr("loaded","true");
				$this.jTree();
				
				initUI($this);
			},false);
		},
		subTree:function(op, level) {
			return this.each(function(){
				$(">li", this).each(function(){
					var $this = $(this);
					setTimeout(function(){
						var isLast = ($this.next()[0]?false:true);
						$this.genTree({
							icon:op.icon,
							ckbox:op.ckbox,
							radio:op.radio,
							exp:isLast?op.options.lastExp:op.options.exp,
							coll:isLast?op.options.lastColl:op.options.coll,
							options:op.options,
							level:level,
							space:isLast?null:op.space,
							showSub:op.showSub,
							isLast:isLast
						});
					},1);		
				});
			});
		},
		genTree:function(options) {
			var op = $.extend({icon:options.icon,ckbox:options.ckbox,radio:options.radio,exp:"", coll:"", showSub:false, level:0, options:null, isLast:false}, options);
			return this.each(function(){
				var node = $(this);
				var tree = $(">ul", node);
					var parent = node.parent().prev();
					var checked = 'unchecked';
					if(op.ckbox) {
						if($(">.checked",parent).size() > 0) checked = 'checked';
					}
				if (tree.size()>0) {
					node.children(":first").wrap("<div></div>");
					//$(">div", node).prepend("<div class='" + (op.showSub ? op.coll : op.exp) + "'></div>"+(op.ckbox ?"<div class='ckbox unchecked'></div>":op.radio?"<div class='ckbox unchecked'></div>":"")+(op.icon?"<div class='"+ (op.showSub ? op.options.folderColl : op.options.folderExp) +"'></div>":""));
					$(">div", node).prepend("<div class='" + (op.showSub ? op.coll : op.exp) + "'></div>"+(op.ckbox||op.radio ?"<div class='ckbox " + checked + "'></div>":"")+(op.icon?"<div class='"+ (op.showSub ? op.options.folderColl : op.options.folderExp) +"'></div>":""));
					op.showSub ? tree.show() : tree.hide();
					$(">div>div:first,>div>a", node).click(function(){
						var $fnode = $(">li:first",tree);
						if($fnode.children(":first").isTag('a')) tree.subTree(op, op.level + 1);
						var $this = $(this);
						var isA = $this.isTag('a');
						var $this = isA?$(">div>div", node).eq(op.level):$this;
						if (!isA || tree.is(":hidden")) {
							$this.toggleClass(op.exp).toggleClass(op.coll);
							if (op.icon) {
								$(">div>div:last", node).toggleClass(op.options.folderExp).toggleClass(op.options.folderColl);
							}
						}
						(tree.is(":hidden"))?tree.slideDown("fast",tree.bindTree):(isA?"":tree.slideUp("fast"));
						return false;
					});
					addSpace(op.level, node);
					if(op.showSub) tree.subTree(op, op.level + 1);
				} else {
					node.children().wrap("<div></div>");			
					$(">div", node).prepend("<div class='node'></div>"+(op.ckbox?"<div class='ckbox unchecked'></div>":op.radio?"<div class='ckbox unchecked'></div>":"")+(op.icon?"<div class='file'></div>":""));
					addSpace(op.level, node);
					if(op.isLast)$(node).addClass("last");
				}
				if (op.ckbox||op.radio) node._check(op);
				//if (op.ckbox) node._check(op);
				//if (op.radio) node._radio(op);
				$(">div",node).mouseover(function(){
					$(this).addClass("hover");
				}).mouseout(function(){
					$(this).removeClass("hover");
				});
				if($.browser.msie)
					$(">div",node).click(function(){
						$("a", this).trigger("click");
						return false;
					});
			});
			function addSpace(level,node) {
				if (level > 0) {					
					var parent = node.parent().parent();
					var space = !parent.next()[0]?"indent":"line";
					var plist = "<div class='" + space + "'></div>";
					if (level > 1) {
						var next = $(">div>div", parent).filter(":first");
						var prev = "";
						while(level > 1){
							prev = prev + "<div class='" + next.attr("class") + "'></div>";
							next = next.next();
							level--;
						}
						plist = prev + plist;
					}
					$(">div", node).prepend(plist);
				}
			}
		},
		_check:function(op) {
			var node = $(this);
			var ckbox = $(">div>.ckbox", node);
			var $input = node.find("a");
			ckbox.append("<input type='"+(op.ckbox?"checkbox":"radio")+"' name='" + $input.attr("tname") + "' value='" + $input.attr("tvalue") + "' style='display:none;'/>")
			.click(function(){
				var cked = ckbox.hasClass("checked");
				var aClass = cked?"unchecked":"checked";
				var rClass = cked?"checked":"unchecked";
				if(op.ckbox){
					ckbox.removeClass(rClass).removeClass(!cked?"indeterminate":"").addClass(aClass);
					$("input", ckbox).attr("checked", !cked);
					$(">ul", node).find("li").each(function(){
						var box = $("div.ckbox", this);
						box.removeClass(rClass).removeClass(!cked?"indeterminate":"").addClass(aClass)
						   .find("input").attr("checked", !cked);
					});
					$(node)._checkParent();
				}else{
					var $tree = node.parents("ul.tree");
					$tree.find("div.ckbox").removeClass("checked").addClass("unchecked").find("input").attr("checked",false);
					//var box = $("div.ckbox", this);
					ckbox.removeClass("unchecked").addClass("checked").find("input").attr("checked",true);
				}
				return false;
			});
			var cAttr = $input.attr("checked");
			if(cAttr) cAttr = eval(cAttr);
			if (cAttr) {
				ckbox.find("input").attr("checked", true);
				ckbox.removeClass("unchecked").addClass("checked");
				$(node)._checkParent();
			}
		},
		_checkParent:function(){
			if($(this).parent().hasClass("tree")) return;
			var parent = $(this).parent().parent();
			var stree = $(">ul", parent);
			var ckbox = stree.find(">li>a").size()+stree.find("div.ckbox").size();
			var ckboxed = stree.find("div.checked").size();
			var aClass = (ckboxed==ckbox?"checked":(ckboxed!=0?"indeterminate":"unchecked"));
			var rClass = (ckboxed==ckbox?"indeterminate":(ckboxed!=0?"checked":"indeterminate"));
			$(">div>.ckbox", parent).removeClass("unchecked").removeClass(rClass).addClass(aClass);
			parent._checkParent();
		},
		_radio:function(op){
			self.prev=[];
			var node = $(this);
			var radio = $(">div>.radio", node);
			var $input = $("a", node);
			var reflush=function($this){
				$this.data("indeterminate", $this.hasClass("indeterminate"))
					 .data("aClass",$this.data("indeterminate")?"unchecked":"indeterminate")
				     .data("rClass",$this.data("indeterminate")?"indeterminate":"unchecked")
					 .removeClass($this.data("rClass")).removeClass(!$this.data("indeterminate")?"indeterminate":"").addClass($this.data("aClass"));
				$("input", $this).attr("checked", !$this.data("checked"));
//				$(">ul", node).find("li").each(function(){
//					var box = $("div.radio", this);
//					box.removeClass($this.data("rClass")).removeClass(!$this.data("checked")?"indeterminate":"").addClass($this.data("aClass"))
//					   .find("input").attr("checked", !$this.data("checked"));
//				});
			}
			//debugger;
			radio.append("<input type='radio' name='" + $input.attr("tname") + "' value='" + ($input.attr("tvalue")||true) + "' style='display:none;'/>")
				.each(function(){
					var $this = $(this);
					$this.click(function(){
						if(self.prev[0]&&self.prev[0]==$this) return false;
						
						reflush($this);
						//debugger;
						if(self.prev.length>0)reflush(self.prev[0]);
						self.prev.splice(0,self.prev.length,$this);
						return false;
					});
				});
			
		},
		_treemenu:function(){ // tree右键菜单
			var $this = this;
			$this.contextMenu('treePopCM', {
				bindings:{
					insBrother:function(t,m){
						var a=t.find(">div>a"),menu=m.find("[rel='insBrother']");
						var parentId = a.attr("parent_id"),entity=a.attr("entity");
						var url = !parentId||parentId==0?menu.attr("actionRoot").bind({entity:entity}):menu.attr("action").bind({category_id:parentId});
						title = a.text()+"->新增同级目录";
						$.pdialog.open(url, "insBrother", title,{},function(data){
							//debugger;
							//$this._reload(t, true);
							$this.parent().reload();
						});
					},
					insChildren:function(t,m){
						var a=t.find(">div>a"),menu=m.find("[rel='insChildren']");
						var categoryId = a.attr("category_id");
						
						var url = menu.attr("action").bind({category_id:categoryId});
						title = a.text()+"->新增子目录";
						$.pdialog.open(url, "insChildren", title,{},function(data){
							/*
							if($this.find(">ul").length==0){
								$this.find(">div>div.file").removeClass("file").addClass("folder_expandable");
								var level=$this.parent().attr("level")+1;
								var categoryId=$this.find(">div>a").attr("category_id");
								var ul="<ul level='"+level+"' action='/category/{category_id}/children' category_id='"+categoryId+"' loaded='false' style='display: none;'><li><a>请稍后...</a></li></ul>";
								$this.append(ul);
							}
							*/
							//$this.find(">ul").reload();
							$this.parent().reload();
						});
					},
					edit:function(t,m){
						var a=t.find(">div>a"),menu=m.find("[rel='edit']");
						var categoryId = a.attr("category_id");
						
						var url = menu.attr("action").bind({category_id:categoryId});
						title = a.text()+"->新增子目录";
						$.pdialog.open(url, "edit", title,{},function(data){
							//debugger;
							//$this.find(">ul").reload();
							a.text(data.name);
						});
					},
					del:function(t,m){
						var a=t.find(">div>a"),menu=m.find("[rel='del']");
						var categoryId = a.attr("category_id");
						
						var url = menu.attr("action").bind({category_id:categoryId});
						alertMsg.confirm("确定删除目录【"+a.text()+"】?", {
							okCall: function(){
								navTabTodo(url,{
										callback: callback,
										type:"delete"
									});
							}
						});
						
						function callback(data){
							var rel= a.attr("rel");
							navTab.closeTab(rel);
							$this.parent().reload();
							//$this.remove();
						}
					},
					rule:function(t,m){
						var a=t.find(">div>a"),menu=m.find("[rel='rule']");
						var categoryId = a.attr("category_id");
						
						var url = menu.attr("action").bind({category_id:categoryId});
						title = a.text()+"->规则管理";
						$.pdialog.open(url, "rule", title,{width:800,height:400},function(data){
							//debugger;
							//$this.find(">ul").reload();
//							a.text(data.name);
						});
					}
				},
				ctrSub:function(t,m){
					var mInsBrother = m.find("[rel='insBrother']");
					var mInsChildren = m.find("[rel='insChildren']");
					var mEdit = m.find("[rel='edit']");
					var mDel = m.find("[rel='del']");
					var mRule = m.find("[rel='rule']");
					var entity=t.find(">div>a").attr("entity");
					if(!entity){
						mRule.addClass("disabled");
					}
				}
			});
		}
	});
})(jQuery);